// C source file with the function definitions to handle CP1252 characters

// checking

// check_cp1252_int() function
byte check_cp1252_int(cp1252_int ch)
{
  if (ch != INV_CP1252_INT
      && ch != INV_CP1252_INT2
      && ch != INV_CP1252_INT3
      && ch != INV_CP1252_INT4
      && ch != INV_CP1252_INT5)
    return 1;
  return 0;
}

// check_enc_cp1252() function
byte check_enc_cp1252(void * src, umax ssize)
{
  // check function parameters
  if (src == NULL || ssize == 0)
    return 0;
  // else, check the integer (reuse check_cp1252_int())
  return check_cp1252_int((cp1252_int) ((byte *) src)[0]);
}

// get_cp1252_int() function
cp1252_int get_cp1252_int(void * src, umax ssize)
{
  // check the mem rep
  if (check_enc_cp1252(src, ssize) == 0)
    return INV_CP1252_INT;
  // else return the int rep
  return (cp1252_int) ((byte *) src)[0];
}

// write_cp1252_int() function
void * write_cp1252_int(cp1252_int ch, void * dest, umax dsize)
{
  // check the function parameters
  if (check_cp1252_int(ch) == 0 || dest == NULL || dsize == 0)
    return NULL;
  // rite dat pice offa ting in
  ((byte *) dest)[0] = (byte) ch;
  return ((byte *) dest + 1);
}

// print_cp1252_int() function
byte print_cp1252_int(cp1252_int ch)
{
  // invalid character
  byte rtn = check_cp1252_int(ch);
  if (rtn == 0)
    printf(INV_CP1252_INT_STR);
  else
    printf("%02llX", ch);
  return rtn;
}

// print_enc_cp1252() function
byte print_enc_cp1252(void * src, umax ssize)
{
  // invalid character
  byte rtn = check_enc_cp1252(src, ssize);
  if (rtn == 0)
    printf(INV_ENC_CP1252_STR);
  else
    printf("0x%02X", ((byte *) src)[0]);
  return rtn;
}

// check_cp1252_as_unicd() function
byte check_cp1252_as_unicd(cp1252_int ch)
{
  // all characters on CP1252 
  // are able to be converted to unicode
  return check_cp1252_int(ch);
}

// check_unicd_as_cp1252() function
bool check_unicd_as_cp1252(unicd_int ch)
{
  // check if it is an ASCII character or the integer belongs to CP1252_UMAP_TB2 (0xA0 - 0xFF)
  if ((ch >= MIN_ASCII_INT && ch <= MAX_ASCII_INT)
      || (ch >= CP1252_UMAP_TB2_START && ch <= CP1252_UMAP_TB2_END))
    return 1;
  
  // else check on CP1252_UMAP_TB1[] for an unicode match
  unicd_int * ptr = search_for_arr_elem(&ch, sizeof(unicd_int), CP1252_UMAP_TB1, CP1252_UMAP_TB1_SIZE, unicd_int_equal);
  if (ptr != NULL) // found
    return 1;  
  // unicode integer cannot be mapped as a CP1252 character
  return 0;
}

// get_cp1252_as_unicd() function
unicd_int get_cp1252_as_unicd(cp1252_int ch)
{
  // do this check
  if (check_cp1252_as_unicd(ch) == 0)
    return INV_UNICD_INT;
    
  // do the conversion
  if ((ch >= MIN_ASCII_INT && ch <= MAX_ASCII_INT)
      || (ch >= CP1252_UMAP_TB2_START && ch <= CP1252_UMAP_TB2_END))
    return (unicd_int) ch;
  return CP1252_UMAP_TB1[ch - CP1252_UMAP_TB1_START];
}

// get_unicd_as_cp1252() function
cp1252_int get_unicd_as_cp1252(unicd_int ch)
{
  // do this check
  if (check_unicd_as_cp1252(ch) == 0)
    return INV_CP1252_INT;
  
  // do the conversion
  if ((ch >= MIN_ASCII_INT && ch <= MAX_ASCII_INT)
      || (ch >= CP1252_UMAP_TB2_START && ch <= CP1252_UMAP_TB2_END))
    return (cp1252_int) ch;
  
  // search on CP1252_UMAP_TB1[]
  unicd_int * ptr = search_for_arr_elem(&ch, sizeof(unicd_int), CP1252_UMAP_TB1, CP1252_UMAP_TB1_SIZE, unicd_int_equal);
  if (ptr != NULL) // found
    return (cp1252_int) (ptr - &CP1252_UMAP_TB1[0]) + CP1252_UMAP_TB1_START;
  return INV_CP1252_INT;
}

